package gee

import (
	"net/http"
	"strings"
)

type router struct {
	roots    map[string]*Node
	handlers map[string]HandlerFunc
}

func newRouter() *router {
	return &router{
		handlers: make(map[string]HandlerFunc),
		roots:    make(map[string]*Node),
	}
}

//插入进前缀树
func (r *router) addRoute(method, pattern string, handler HandlerFunc) {
	//check
	parts := parsePattern(pattern)
	key := method + "-" + pattern
	_, ok := r.roots[method]
	if !ok {
		r.roots[method] = &Node{}
	}
	r.roots[method].insert(pattern, parts, 0)
	r.handlers[key] = handler
}

//从前缀树中获取路由，并且取其参数
func (r *router) searchRoute(method, path string) (*Node, map[string]string) {
	searchParts := parsePattern(path)
	root, ok := r.roots[method]
	if !ok {
		return nil, nil
	}
	resNode := root.search(searchParts, 0)
	if resNode == nil {
		return resNode, nil
	}

	params := make(map[string]string)
	parts := parsePattern(resNode.pattern)
	for i, part := range parts {
		if part[0] == ':' {
			params[part[1:]] = searchParts[i]
		}
		if part[0] == '*' && len(part) > 1 {
			params[part[1:]] = strings.Join(searchParts[i:], "/")
			break
		}
	}
	return resNode, params

}

// 解析路由参数
func parsePattern(pattern string) (parts []string) {
	arr := strings.Split(pattern, "/")

	parts = make([]string, 0)
	for _, item := range arr {
		if item != "" {
			parts = append(parts, item)
			if item[0] == '*' {
				break
			}
		}
	}
	return
}

func (r *router) handle(c *Context) {
	node, params := r.searchRoute(c.Method, c.Path)
	if node != nil {
		c.Params = params
		key := c.Method + "-" + node.pattern
		c.handlers = append(c.handlers, r.handlers[key])
	} else {
		c.handlers = append(c.handlers, func(c *Context) {
			c.String(http.StatusNotFound, "404 NOT FOUND:%s\n", c.Path)
		})
	}
	c.Next()
}
